# -*- coding: utf-8 -*-

import wx
import sys
import os
from threading import Thread
import time

from comun import mensageError as msje, mensageAlerta as msja, mensajePregunta as msjp
from contrasenhas.modelo import Modelo  

class Controlador():
    
    def __init__(self,vista):
        """
        Constructor de la clase
        :param vista: La vista que lo llamó
        """
        
        self.vista = vista
        self.treePresionado = None
        self.listCtrlPresionado = None
        self.itemsCateorias = []
        """ ALMACENA LOS ITEMS DE LAS CATEGORIAS EN UNA LISTA """
        
        # IMPORTAMOS EL MODELO
        self.modelo = Modelo(self)
    
    def verificarBDAbierta(self,evt):
        
        
        idElemento = evt.GetId()
        """ Obtenemos el id del elemento que activó el evento """
        
        self.vista.crearBD()
    
    def verificarAbrirBd(self,evt):
        
        self.vista.abrirBD()
    
    def verificarCerrarBD(self,evt):
        
        if msjp(self.vista,"¿Está seguro que desea cerrar la base de datos?"):
            msja(self.vista,"La base de datos fue cerrada correctamente")
    
    def crearBaseDatos(self,nombre,clave,confirmacion):
        
        # CAPTURAMOS LOS VALORES DE LA VISTA
        varNombre = nombre.GetValue().encode('utf8').strip()
        varClave = clave.GetValue().encode('utf8').strip()
        varConfirmacion = confirmacion.GetValue().encode('utf8').strip()
        
        # IMPRIMIMOS LOS VALORES RECIBIDOS DE LA VISTA
        if varNombre == '':
            msja(self.vista.ventanaHija,"Debe ingresar el nombre de la base de datos")
            nombre.SetFocus()
        elif varClave == "":
            #self.vista.ventanaHija.msja(self.vista.ventanaHija,"Debe ingresar una clave")
            msja(self.vista.ventanaHija,"Debe ingresar una clave")
            clave.SetFocus()
        elif varConfirmacion == "":
            #self.vista.ventanaHija.msja(self.vista.ventanaHija,"Debe ingresar la confiramción de la clave")
            msja(self.vista.ventanaHija,"Debe ingresar la confiramción de la clave")
            confirmacion.SetFocus()
        elif varClave != varConfirmacion:
            #self.vista.ventanaHija.msje(self.vista.ventanaHija,"La clave y la confirmación no son iguales. Ingreselas de nuevo")
            msje(self.vista.ventanaHija,"La clave y la confirmación no son iguales. Ingreselas de nuevo")
            clave.SetFocus()
        
        else:
            msja(self.vista.ventanaHija,"Los datos fueron ingresados correctamente")
            self.vista.ventanaHija.cerrarVentana(0)
            self.vista.ventanaHija = None
    
    
    def abrirBD(self,nombre,clave):
        
        nombre = nombre.encode('utf8').strip()
        clave = clave.encode('utf8').strip()
        if nombre == "":
            msja(self.vista.ventanaHija,"Debe ingresar el nombre de la base de datos")
        elif clave == "":
            msja(self.vista.ventanaHija,"Debe ingresar una clave")
        else:
            
            #self.vista.ventanaHija.parent.txtPanelC.SetLabel("¡Conectado a la base de datos \"%s\"!" % nombre)
            self.listarCategorias
            self.vista.ventanaHija.cerrarVentana(0)
    
    def listarCategorias(self,encontrar=True):
        
        
        categorias = self.modelo.listarCategorias()
        if categorias and encontrar:
            for c in categorias:
                child = self.vista.tree.AppendItem(self.vista.root,c)
                self.itemsCateorias.append(child)
                self.vista.tree.SetPyData(child, None)
                self.vista.tree.SetItemImage(child, self.vista.fldropenidx, wx.TreeItemIcon_Normal)
                self.vista.tree.SetItemImage(child, self.vista.fldridx, wx.TreeItemIcon_Expanded)
            
            return True
        
        
        
        return categorias
    
    def treeSeleccionado(self,evt):
        
        self.vista.listCtrl.DeleteAllItems()
        self.treePresionado = evt.GetItem()
        texto = self.vista.tree.GetItemText(self.treePresionado).encode('utf8')
        if texto:
             
            texto = self.vista.tree.GetItemText(self.treePresionado).encode('utf8')
            datos = self.modelo.listarClavesPorCategorias(texto)
            for clave, valor in datos:
                index = self.vista.listCtrl.InsertImageStringItem(sys.maxint,valor['titulo'],self.vista.imagenLista)
                self.vista.listCtrl.SetStringItem(index, 1, valor['usuario'])
                self.vista.listCtrl.SetStringItem(index, 2, valor['contrasenha'])
                self.vista.listCtrl.SetStringItem(index, 3, valor['comentarios'])
                self.vista.listCtrl.SetItemData(index,clave)
        
        
    def listDerechoAbajo(self,evt):
        """ Método que selecciona un Grupo se hace click derecho """
        evt.Skip()
        
    
    def treeDerechoAbajo(self,evt):
        """ Método que selecciona un Grupo se hace click derecho """
        evt.Skip()
        
    def treeClickDerecho(self,evt):
        """ Método que crea el menu emergente para un grupo seleccionado """
        if self.treePresionado != None: 
            if not hasattr(self, "popupID1"):
                self.popupID1 = wx.NewId()
                self.popupID2 = wx.NewId()
                self.vista.Bind(wx.EVT_MENU, self.editarCategoria, id=self.popupID1)
                self.vista.Bind(wx.EVT_MENU, self.eliminarCategoria, id=self.popupID2)
                
            self.vista.menu = wx.Menu()
            self.vista.menu.Append(self.popupID1, "Editar")
            self.vista.menu.Append(self.popupID2, "Eliminar")
            self.vista.PopupMenu(self.vista.menu)
            self.vista.menu.Destroy()
        
    
    def OnItemSelected(self,evt):
        """ Método que captura el listCtrl Seleccionado """
        self.listCtrlPresionado = evt.m_itemIndex
    
    def listClickDerecho(self,evt):
        
        """ Método que crea el menu emergente para un grupo seleccionado """
        #item = self.vista.listCtrl.GetColumn(self.listCtrlPresionado)
        ##texto1 = self.vista.listCtrl.GetItem(self.listCtrlPresionado, 0).GetText()
        ##texto2 = self.vista.listCtrl.GetItem(self.listCtrlPresionado, 1).GetText()
        #self.vista.listCtrl.GetItemText(item)
        ##print texto1, texto2
        
        if self.listCtrlPresionado != None: 
            if not hasattr(self, "popupID1List"):
                self.popupID1List = wx.NewId()
                self.popupID2List = wx.NewId()
                self.vista.Bind(wx.EVT_MENU, self.editarClave, id=self.popupID1List)
                self.vista.Bind(wx.EVT_MENU, self.eliminarClave, id=self.popupID2List)
                
            self.vista.menu = wx.Menu()
            self.vista.menu.Append(self.popupID1List, "Editar")
            self.vista.menu.Append(self.popupID2List, "Eliminar")
            self.vista.PopupMenu(self.vista.menu)
            self.vista.menu.Destroy()
        
                
    def editarClave(self,evt):
        """ Método que llama al Frame que permite Editar una clave """
        
        titulo = self.vista.listCtrl.GetItem(self.listCtrlPresionado, 0).GetText()
        usuario = self.vista.listCtrl.GetItem(self.listCtrlPresionado, 1).GetText()
        #contrasenha = self.vista.listCtrl.GetItem(self.listCtrlPresionado, 2).GetText()
        contrasenha = '123'
        confirmacion = contrasenha
        comentario = self.vista.listCtrl.GetItem(self.listCtrlPresionado, 3).GetText()
        
        win = self.vista.FrameModificarClave(self.vista, -1, u"Modificar Contraseña", titulo, usuario,contrasenha,confirmacion,comentario, size=(390, 350))
        
        win.Show(True)
        #print win.GetId()
        self.vista.parent.Enable(False)
    
    def eliminarClave(self,evt):
        
        """ Método que llama la ventan de confirmación para proceder a elimnar una clave """
        if msjp(self.vista,"¿Está seguro que desea eliminar la clave?"):
            self.vista.listCtrl.DeleteItem(self.listCtrlPresionado)
        
        
    def editarCategoria(self,evt):
        
        win = self.vista.FrameEditarCategoria(self.vista, -1, "Modificar Categoría", size=(280, 120),
                  style = wx.DEFAULT_FRAME_STYLE)
        
        win.Show(True)
        self.vista.parent.Enable(False)
    
    def eliminarCategoria(self,evt):
        
        self.vista.tree.DeleteChildren(self.treePresionado)
        self.vista.tree.Delete(self.treePresionado)
        self.itemsCateorias.remove(self.treePresionado)
        self.treePresionado = None
        
    
    def accionEditarCategoria(self,nombre):
        
        self.vista.tree.SetItemText(self.treePresionado,nombre.GetValue().encode('utf8'))
        self.vista.ventanaHija.cerrarVentana(0)
    
    
    def borrarPapelera(self,evt):
        
        if msjp(self.vista,"¿Esta seguro de querer eliminar los datos de la papelera de forma permanente del sistema?"):
            
            self.EJECUTADOS = 0
            """ ESTA VARAIBLE SERÁ LA QUE PERMITA LA COMUNICACIÓN ENTRE EL THREAD Y LA BARRA DE ESTADO """
            
            
            rutaPapelera = os.getenv('HOME') + '/.local/share/Trash/files/'
            """ RUTA DE LA PAPELERA DEL USUARIO CONECTADO """
            
            
            listaArchivos = ['a1.txt','a2.txt','a3.txt','a4.txt','a5.txt']
            
            self.worker = ThreadBorrarPapelera(self,listaArchivos)
            """ Hacemos llamado a al Thread para que comience a borrar la papelera """
            
            # EL CODIGO DE AQUI SE EJECUTA AUNQUE NO SE HAYA TERMINADO DE EJECUTAR ThreadBorrarPapelera
            # CREAMOS EL MENSJAE DE BORRADO 
            dlg = wx.ProgressDialog("Barra de progreso","Borrando archivos",
                               maximum = len(listaArchivos), # Tiempo maximo a esperar
                               parent=self.vista, # La ventana va a estar atada a la vista de este controlador
                               style = wx.PD_CAN_ABORT
                                #wx.PD_APP_MODAL
                                #| wx.PD_ELAPSED_TIME
                                #| wx.PD_ESTIMATED_TIME
                                #| wx.PD_REMAINING_TIME
                                )
            # BANDERA QUE PERMITRÁ SALIR DEL MENSAJE EN CASO DEL USUARIO CANCELAR
            keepGoing = True
            # LA VARIABLE EJECUTADOS CAMBIA DE VALOR DENTRO DEL THREAD
            
            max = len(listaArchivos)
             
            while self.EJECUTADOS < max and keepGoing:
                
                if self.EJECUTADOS == 0 and max > 1:
                    ejecutados = 1
                else:
                    ejecutados = self.EJECUTADOS
                    
                #print self.EJECUTADOS
                # A MEDIDA QUE EJECUTADOS AUMENTA DE VALOR, LA BARRA DE ESTADO COMIENZA A AUMENTAR EN LA IMAGEN
                (keepGoing, skip) = dlg.Update(ejecutados)
                
            # UNA VEZ EJECUTADOS TODOS LOS ARCHIVOS A BORRAR, SE PROCEDE A DESTRUIR EL DIÁLOGO
            dlg.Destroy()
            
            return u'¡Los archivos fueron eliminados exitosamente!'
            
        return u"¡La pepelera no fue borrada!"
    
    
class ThreadBorrarPapelera(Thread):

    def __init__(self, controlador, listaArchivos):
        """ Constructor de la clase """

        Thread.__init__(self)
        """ LLAMADO A CONSTRUCTOR PADRE """
        self.listaArchivos = listaArchivos
        """ LISTA DE ARCHIVOS A SER BORRADOS """
        
        self._controlador = controlador
        """ Almacenamos el controlador para porder Acceder a la variable de EJECUTADOS """
        
        self.start()

    def run(self):
        """ Proceso Thread que se encargará de borrar la papelera """
        
        for archivo in self.listaArchivos:
            # AQUI BORRAMOS LOS ARCHIVOS 
            # DE MOMENTO NO VAMOS A BORRAR, PERO HAREMOS EL SIMULACRO DE QUE CADA BORRADA DE ARCHIVO DURA 3 SEGUNDOS
            time.sleep(3)
            self._controlador.EJECUTADOS+=1